﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Castle.Facilities.NHibernateIntegration;
using Castle.Services.Transaction;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
using OrderSystem.Core.Domain;
using OrderSystem.Core.Manager;
using Configuration=NHibernate.Cfg.Configuration;
using ITransaction=NHibernate.ITransaction;

namespace OrderSystem.Win
{
    public partial class MainForm : Form
    {
        private readonly IWindsorContainer container;

        private Order order;
        private Customer customer;
        private Product product1;
        private Product product2;
        private Product product3;
        private readonly IBaseEntityManager<Product> productManager;
        private readonly IBaseEntityManager<Customer> customerManager;
        private readonly IBaseEntityManager<Order> orderManager;

        private List<Order> orderList = new List<Order>();

        private readonly ISessionFactory sessionFactory;
        private ISessionManager sessionManager;

        public MainForm()
        {
            InitializeComponent();

            container = new WindsorContainer(new XmlInterpreter());

            var cfg = container.Resolve<Configuration>();

            sessionManager = container.Resolve<ISessionManager>();

            sessionFactory = cfg.BuildSessionFactory();

            new SchemaExport(cfg).Drop(false, true);
            new SchemaExport(cfg).Create(false, true);

            productManager = container.Resolve<IBaseEntityManager<Product>>();
            customerManager = container.Resolve<IBaseEntityManager<Customer>>();
            orderManager = container.Resolve<IBaseEntityManager<Order>>();

            try
            {
                FillReference();
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
            }
            //MsSqlDbUtility.CreateDbOnly(configuration.Properties["connection.connection_string"], true);


            //new SchemaExport(configuration).Execute(false, true, false);
        }

        
        private void FillReference()
        {
//            using (ISession session = sessionFactory.OpenSession())
            using (ISession session = sessionManager.OpenSession())

            {
//                using (ITransaction transaction = session.BeginTransaction())
                //using (ITransaction transaction = session.BeginTransaction())
                {
                    customer = new Customer {Name = "Customer Name", Tag = "Customer Tag"};
                    product1 = new Product {Name = "Product1 name", Tag = "Product1 tag"};
                    product2 = new Product {Name = "Product2 name", Tag = "Product2 tag"};
                    product3 = new Product {Name = "Product3 name", Tag = "Product3 tag"};

                    customerManager.Save(customer);
                    productManager.Save(product1);
                    productManager.Save(product2);
                    productManager.Save(product3);

//                    session.SaveOrUpdate(customer);
//
//                    session.SaveOrUpdate(product1);
//                    session.SaveOrUpdate(product2);
//                    session.SaveOrUpdate(product3);

                    order = new Order
                                {
                                    CreationDate = DateTime.Now,
                                    Number = "1X",
                                    Customer = customer,
                                    Tag = "order1 tag",
                                };

                    var orderItem1 = new OrderItem
                                         {
                                             Order = order,
                                             Product = product1,
                                             Quantity = 10
                                         };

                    var orderItem2 = new OrderItem
                                         {
                                             Order = order,
                                             Product = product2,
                                             Quantity = 20
                                         };


                    order.OrderItems = new List<OrderItem> {orderItem1, orderItem2};
                    //session.SaveOrUpdate(order);

                    orderManager.Save(order);

                    //transaction.Commit();
                }
            }
        }


        //[Transaction(TransactionMode.Requires)]
        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                productManager.Delete(product1);
            }
            catch (Exception Err)
            {
                MessageBox.Show(this, Err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        //[Transaction(TransactionMode.Requires)]
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                int orderNumber = orderList.Count + 1;

                order = new Order
                            {
                                CreationDate = DateTime.Now,
                                Number = orderNumber + "X",
                                Customer = customer,
                                Tag = "order" + orderNumber + " tag",
                            };

                var orderItem1 = new OrderItem
                                     {
                                         Order = order,
                                         Product = product1,
                                         Quantity = 10
                                     };

                var orderItem2 = new OrderItem
                                     {
                                         Order = order,
                                         Product = product2,
                                         Quantity = 20
                                     };


                order.OrderItems = new List<OrderItem> {orderItem1, orderItem2};
                orderManager.Save(order);

                orderList.Add(order);

                if (orderList.Count > 0)
                {
                    numericUpDown1.Enabled = true;
                    numericUpDown1.Maximum = orderList.Count - 1;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(this, err.Message);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //using (ISession session = sessionFactory.OpenSession())
            {
                //using (ITransaction transaction = session.BeginTransaction())
                {
                    if (!numericUpDown1.Enabled) return;

                    var editOrder = orderList[(int) numericUpDown1.Value];

                    editOrder.Number = "XXX";
                    editOrder.CreationDate = DateTime.Now.AddMonths(1);

                    editOrder.OrderItems[0].Product = product3;
                    editOrder.OrderItems[0].Quantity = 11;

                    editOrder.OrderItems.RemoveAt(1);

                    editOrder.OrderItems.Add(new OrderItem {Order = editOrder, Product = product3, Quantity = 111});

                    orderManager.Save(editOrder);
                    //session.SaveOrUpdate(editOrder);

                    //transaction.Commit();
                }
            }
        }

        //[Transaction(TransactionMode.Requires)]
        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                orderList = new List<Order>(orderManager.GetAll());

                if (orderList.Count > 0)
                {
                    numericUpDown1.Enabled = true;
                    numericUpDown1.Maximum = orderList.Count - 1;
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(this, err.Message);
            }
        }

        //[Transaction(TransactionMode.Requires)]
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                productManager.Save(new Product {Name = "Product4 name", Tag = "Product4 tag"});
            }
            catch (Exception err)
            {
                MessageBox.Show(this, err.Message);
            }
        }
    }
}